/*
	This file is part of "Ants on the web".

    "Ants on the web" is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    "Ants on the web" is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with "Ants on the web".  If not, see <http://www.gnu.org/licenses/>.
*/

package org.utc.ia04.antsontheweb.utilities;

import jade.core.AID;
import jade.core.Agent;
import jade.domain.AMSService;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.lang.acl.ACLMessage;

import java.io.Serializable;
import java.io.StringWriter;

import org.codehaus.jackson.map.ObjectMapper;
import org.utc.ia04.antsontheweb.gui.surveillance.AgentInterfaceSurveillance;
import org.utc.ia04.antsontheweb.httprequest.agent.HttpReqPoolManager;

public class Requete implements Serializable
{
	//serialVersionUID
	private static final long serialVersionUID = 8571028780569843244L;
	
	//Erreurs possibles
	public static final int KB_ERROR = -1;
	public static final int PHEROMONE_ERROR = -2;
	
	//Types de requetes
	public static final int HTTPREQ_TO_PARSER = 0;
	public static final int KB_LEARN = 1;
	public static final int KB_GIVE_WEBSITE_TYPE = 2;
	public static final int KB_STATEMENT = 3;
	public static final int AC_GO = 4;
	public static final int AC_DEATH = 5;
	public static final int ANT_GO = 6;
	public static final int ANTPARSER_RESSOURCEPICKUP = 7;
	public static final int ANTPARSER_ASKFORPHEROMONE = 8;
	public static final int ANT_DYING = 10;
	public static final int ANT_UPDATEPHEROMONE = 11;
	public static final int AC_ASKRESULT = 12;
	public static final int GUI_ENDSIMULATION = 13;
	public static final int PHEROMONEMANAGER_SENDLINKSWITHPH = 14;
	public static final int ANTPATHFINDER_ASKHTMLCONTENT = 15;
	public static final int KB_GUI_FORCE_LOAD_URL = 16;
	public static final int KB_ANSWER = 17;
	public static final int PHEROMONEMANAGER_SENDPATHTOGUI= 18;
	public static final int ANT_SENDPARSERAID= 19;
	public static final int REQUESTER_DIE= 20;
	public static final int ANT_RESSOURCEPICKUP = 21;
	public static final int INFORM_BIG_BROTHER = 22;
	public static final int ANTPARSER_DOBACKTRACK = 23;
	public static final int INC_TICK = 24;
	
	//Classe Requete
	private int type;
	private String content;
	
	public Requete()
	{
		type = -1;
		content = "";
	}
	
	public Requete(int type, String content){
		this.type = type;
		this.content = content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public String getContent() {
		return content;
	}

	public void setType(int type) {
		this.type = type;
	}

	public int getType() {
		return type;
	}

	public static Requete deserialize_withException(String s, Agent agent, ACLMessage message) throws RequeteException
	{
		ObjectMapper m = new ObjectMapper();
		try
		{
			Requete q = m.readValue(s, Requete.class);
			return q;
		}
		catch (Exception ex)
		{
			amsMessageManagement(agent, message);
			throw new RequeteException("Erreur de deserialisation");
		}
	}

	public String serialize()
	{
		ObjectMapper m = new ObjectMapper();
		StringWriter sw = new StringWriter();
		try
		{
			m.writeValue(sw, this);
			return sw.toString();
		}
		catch(Exception ex) { return ""; }
	}
	
	public static void amsMessageManagement(Agent agent, ACLMessage message)
	{
		if(message.getPerformative() != ACLMessage.FAILURE)
			return;
		
		try
		{
			AID id = AMSService.getFailedReceiver(agent, message);
			DFAgentDescription ad = new DFAgentDescription(); ad.setName(id);
			DFService.deregister(agent, ad);
			
			String localName = id.getLocalName().toLowerCase();
			if(localName.toLowerCase().contains("ant_"))
				return;
			
			boolean isAnHttpRequester = localName.toLowerCase().contains("httprequester");
			ACLMessage notification = new ACLMessage(ACLMessage.INFORM);
			Requete r = new Requete(isAnHttpRequester ? Requete.REQUESTER_DIE : Requete.INFORM_BIG_BROTHER, localName + "is dead. The simulation could be blocked...");
			notification.setContent(r.serialize());
				
			DFAgentDescription template = new DFAgentDescription();
			ServiceDescription sd = new ServiceDescription();
			sd.setType(isAnHttpRequester ? HttpReqPoolManager.DF_TYPE : AgentInterfaceSurveillance.DF_TYPE);
			template.addServices(sd);
			try
			{
				DFAgentDescription[] result = DFService.search(agent, template);
				for(int i = 0; i < result.length; ++i)
					notification.addReceiver(result[i].getName());
			}
			catch(Exception fe)
				{ System.out.println(fe.getMessage()); }
				
			agent.send(notification);
		}
		catch (FIPAException e)
		{ /* This is not an AMS message... */ }
	}
}
